package com.socool.sinofaith.service.updater;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.socool.sinofaith.R;
import com.socool.sinofaith.service.updater.DownloadThread.DownloadListener;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;

public class DownloadService extends Service {

	private static final String TAG = "DownloadService";

	public static final int DOWNLOAD_STARTED = 0;

	public static final int DOWNLOAD_FINISH = 1;

	public static final int DOWNLOAD_PERCENT = 2;

	public static final int NETWORK_ERROR = 3;

	public static final int SYSTEM_ERROR = 4;

	public static char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7',
			'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

	private ArrayList<Thread> mDownloadList = new ArrayList<Thread>();

	private DownloadThread mDownloadThread;

	private String mLocalPath = null;

	private NotificationManager mNotificationManager;

	private Notification mNotification;

	private int mPercent;

	private String mModel;

	private String mBranch;

	private String mDate;

	private long mUpdateSize;

	private String mMD5Code;

	private MessageDigest mMessageDigest;

	private DownloadServiceListener mListener;

	private Binder mLocalBinder = new LocalBinder();

	private static String zhPattern = "[\u4E00-\u9FA5]";

	public String encode(String str, String charset)
			throws UnsupportedEncodingException {
		Pattern p = Pattern.compile(zhPattern);
		Matcher m = p.matcher(str);
		StringBuffer b = new StringBuffer();
		while (m.find()) {
			m.appendReplacement(b, URLEncoder.encode(m.group(0), charset));
		}
		m.appendTail(b);
		return b.toString();
	}

	public class LocalBinder extends Binder {
		DownloadService getService() {
			return DownloadService.this;
		}
	}

	@Override
	public IBinder onBind(Intent intent) {
//        if(CarWizardSetting.DEBUG){
//		Log.d(TAG, "onBind");
//        }
		return mLocalBinder;
	}

	public void onCreate() {
		super.onCreate();
//        if(CarWizardSetting.DEBUG){
//            Log.d(TAG, "onCreate");    
//        }
	}

	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
//        if(CarWizardSetting.DEBUG){
//            Log.d(TAG, "onStart");
//        }
		if (mDownloadList.size() > 0) {
			// Toast.makeText(DownloadService.this, R.string.downloading_alert,
			// Toast.LENGTH_LONG).show();
			return;
		}

		String url = intent.getStringExtra("package_path");
		mModel = intent.getStringExtra("model");
		mBranch = intent.getStringExtra("branch");
		mDate = intent.getStringExtra("date");

		mUpdateSize = intent.getLongExtra("updateSize", 0l);
		mMD5Code = intent.getStringExtra("updateMD5Code");

		mDownloadThread = new DownloadThread(url);
		mDownloadList.add(mDownloadThread);
		mDownloadThread.setOnDownloadListener(new OtaDownloadListener());
		mDownloadThread.start();

	}

	public void cancel() {

		if (mDownloadThread != null && mDownloadThread.isAlive()) {
			mDownloadThread.cancel();
			mDownloadList.clear();
		}

		if (mNotificationManager != null) {
			mNotificationManager.cancel(TAG, 1024);
		}

	}

	public void setListener(DownloadServiceListener listener) {
		this.mListener = listener;
	}
    
	public class OtaDownloadListener implements DownloadListener {

		public void onDownloadFinish(String localPath) {

			mDownloadList.clear();
			mLocalPath = localPath;
			if (mListener != null) {
				mListener.onDownloadFinish();
			}
			mHandler.sendEmptyMessage(DOWNLOAD_FINISH);

		}

		public void onNetworkException(String localPath) {
			mDownloadList.clear();
			mLocalPath = localPath;
			mHandler.sendEmptyMessage(NETWORK_ERROR);
		}

		public void onDownloadStarted(String localPath) {
			mLocalPath = localPath;
			mHandler.sendEmptyMessage(DOWNLOAD_STARTED);
		}

		public void onDownloadPercent(int percent) {

			if (mListener != null) {
				mListener.onDownloadPercent(percent);
			}

			mPercent = percent;
			mHandler.sendEmptyMessage(DOWNLOAD_PERCENT);

		}
	}
    //获取下载完成的文件的MD5值
	private String getDownloadUpdateMD5Code(File file) throws Exception {
		InputStream fis = new FileInputStream(file);
		byte[] buffer = new byte[1024];
		int numRead = 0;
		mMessageDigest = MessageDigest.getInstance("MD5");
		while ((numRead = fis.read(buffer)) > 0) {
			mMessageDigest.update(buffer, 0, numRead);
		}
		fis.close();
		return bufferToHex(mMessageDigest.digest());
	}

	private String bufferToHex(byte bytes[]) {
		return bufferToHex(bytes, 0, bytes.length);
	}

	private String bufferToHex(byte bytes[], int m, int n) {
		StringBuffer stringBuffer = new StringBuffer(2 * n);
		int k = m + n;
		for (int l = m; l < k; l++) {
			appendHexPair(bytes[l], stringBuffer);
		}
		return stringBuffer.toString();
	}

	private void appendHexPair(byte bt, StringBuffer stringBuffer) {
		char c0 = hexDigits[(bt & 0xf0) >> 4];
		char c1 = hexDigits[bt & 0xf];
		stringBuffer.append(c0);
		stringBuffer.append(c1);
	}
    //判断下载后的文件的MD5值于服务器上文件的MD5值是否相等
	private boolean comparemd5code(String md5code, File file) throws Exception {
		String fileMd5 = getDownloadUpdateMD5Code(file);
		return (md5code.equals(fileMd5)
				|| md5code.equals(fileMd5.toLowerCase()) || md5code
					.equals(fileMd5.toUpperCase()));
	}

	private Handler mHandler = new Handler(Looper.myLooper()) {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);

			switch (msg.what) {

			case DOWNLOAD_FINISH://下载完成

				if (mNotificationManager != null) {
					mNotificationManager.cancel(TAG, 1024);
				}

//				if (CarWizardSetting.DEBUG)
//					Log.d(TAG, "=download finish");
				// Intent intent = new
				// Intent("com.rayhov.intent.UPDATE_CONFIRM");
				// intent.putExtra(Constants.KEY_OTA_PATH, mLocalPath);
				// intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP
				// | Intent.FLAG_ACTIVITY_NEW_TASK);
				// startActivity(intent);

				try {
					File otafile = new File(mLocalPath);
					if (otafile.exists() && otafile.length() == mUpdateSize
							&& comparemd5code(mMD5Code, otafile)) {
						// Intent intent = new Intent(
						// "com.rayhov.intent.OTA_UPDATE");
						// intent.putExtra(LauncherSetting.KEY_OTA_PATH,
						// mLocalPath);
						// sendBroadcast(intent);

					} else if (otafile.exists()
							&& otafile.length() != mUpdateSize
							&& !comparemd5code(mMD5Code, otafile)) {
						otafile.delete();
						Toast.makeText(DownloadService.this, "下载完成",
								Toast.LENGTH_LONG).show();
					}
				} catch (Exception e) {
//					e.printStackTrace();
				}

				stopSelf();

				break;

			case DOWNLOAD_STARTED://开始下载

//				if (CarWizardSetting.DEBUG)
//					Log.d(TAG, "=download started");
				mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
				mNotification = new Notification();
				mNotification.icon = R.drawable.logo;
				mNotification.contentView = new RemoteViews(getPackageName(),
						R.layout.download_notification);
				Intent intent1 = new Intent(DownloadService.this,
						DownloadActivity.class);
				intent1.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
				intent1.putExtra("model", mModel);
				intent1.putExtra("branch", mBranch);
				intent1.putExtra("date", mDate);
				if (mLocalPath != null) {
					intent1.putExtra("localPath", mLocalPath);
				}
				PendingIntent contentIntent = PendingIntent.getActivity(
						DownloadService.this, 0, intent1, 0);
				mNotification.contentIntent = contentIntent;
				mNotification.contentView.setProgressBar(R.id.progress, 100,
						mPercent, false);
				mNotification.contentView.setTextViewText(R.id.title,
						"升级包文件下载中...");
				mNotification.contentView.setTextViewText(R.id.percent,
						mPercent + "%");
				mNotificationManager.notify(TAG, 1024, mNotification);
				Intent downloadIntent = new Intent(DownloadService.this,
						DownloadActivity.class);
				if (mLocalPath != null) {
					downloadIntent.putExtra("localPath", mLocalPath);
				}
				downloadIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				startActivity(downloadIntent);

			case DOWNLOAD_PERCENT://更新进度条

//				if (CarWizardSetting.DEBUG)
//					Log.d(TAG, "====mPercent = " + mPercent);
				mNotification.contentView.setProgressBar(R.id.progress, 100,
						mPercent, false);
				mNotification.contentView.setTextViewText(R.id.percent,
						mPercent + "%");
				mNotificationManager.notify(TAG, 1024, mNotification);

				break;

			case NETWORK_ERROR://下载异常

				Toast.makeText(DownloadService.this, "下载出错", Toast.LENGTH_LONG)
						.show();
				if (mNotificationManager != null) {
					mNotificationManager.cancel(TAG, 1024);
				}
				if (mLocalPath != null) {
					File file = new File(mLocalPath);
					if (file.exists()) {
						file.delete();
					}
				}
				DownloadService.this.stopSelf();

				break;

			}
		}

	};

	public interface DownloadServiceListener {//下载服务接口

		public void onDownloadPercent(int percent);//下载中

		public void onDownloadFinish();//下载完成

	}

}
